import React, { useEffect, useState } from 'react';
import { connect, useDispatch, useSelector } from 'dva';
import { Form, Input, Button, Transfer, Tree } from 'antd';
import { Icon } from 'react-fa';
import Tabs from '@/components/Tabs/Tabs';
import Grid from '@/components/Grid';
import Layout from '@/components/Layout';
import Dialog, { withRef } from '@/components/Dialog';
import settings, { getPagination } from '@/settings';
// import Authorized, { checkRouteAuth } from '@/components/Authorized';
import { createAction } from '@/utils';
import { check } from '@/services/user';
import { getAll as getAllUnits } from '@/services/group';

const { TreeNode } = Tree;

@Form.create()
@connect(({ user }) => ({ ...user }))
@withRef
class ModelForm extends React.Component {
  state = {
    confirmDirty: false,
    selectedKeys: [],
  };
  componentDidMount() {
    const { id, dispatch } = this.props;

    dispatch(createAction('user/fetchGroups')());
    dispatch(createAction('user/fetchRoles')());

    if (id) {
      dispatch(createAction('user/fetchOne')({
        id
      }));
    }
  }
  handleSubmit = (_, callback) => {
    const { form, roleIds } = this.props;

    form.validateFields((err, values) => {
      if (!err) {
        callback({
          ...values,
          roleIds,
        });
      }
    });
  };
  handleChange = targetKeys => {
    const { dispatch } = this.props;
    dispatch(createAction('user/updateState')({
      roleIds: targetKeys,
    }));
  };
  handleConfirmBlur = e => {
    const value = e.target.value;
    this.setState({
      confirmDirty: this.state.confirmDirty || !!value,
    });
  };
  compareToFirstPassword = (rule, value, callback) => {
    const form = this.props.form;
    if (value && value !== form.getFieldValue('password')) {
      callback('两次输入的密码不一致');
    } else {
      callback();
    }
  };
  validateToNextPassword = (rule, value, callback) => {
    const { form } = this.props;
    if (value && this.state.confirmDirty) {
      form.validateFields(['confirmPassword'], {
        force: true,
      });
    }
    callback();
  };
  renderTreeNodes = (data = []) =>
    data.map(item => {
      if (item.children) {
        return (
          <TreeNode title={item.name} selectable={false} key={item.id} dataRef={item} icon={<Icon name="folder-open" />}>
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return (
        <TreeNode {...item} title={item.name} selectable={false} key={item.id} dataRef={item} icon={<Icon name="folder-open" />} />
      );
    });
  onCheck = (checkedKeys, { checked, node }) => {
    const { dispatch } = this.props;
    let _checkedKeys = []
    if (checked) {
      _checkedKeys = [node.props.id]
    }
    dispatch(createAction('user/updateState')({
      groupIds: _checkedKeys
    }));
  };
  onSelect = (selectedKeys, { selected, node }) => {
    const { dispatch } = this.props;
    let _checkedKeys = []
    if (selected) {
      _checkedKeys = [node.props.id]
    }
    dispatch(createAction('user/updateState')({
      groupIds: _checkedKeys
    }));
  };
  onLoadData = async treeNode => {
    const { dispatch, groups } = this.props;
    if (!treeNode.props.children) {
      const { data } = await getAllUnits({
          id: treeNode.props.id
      })
      treeNode.props.dataRef.children = data

      dispatch(createAction('user/updateState')({
        groups: [...groups]
      }))
    }
  }

  render() {
    const {
      id,
      roleIds: targetKeys,
      data = {},
      roles = [],
      groups = [],
      groupIds: checkedKeys,
      form: { getFieldDecorator },
    } = this.props

    return (
      <Tabs defaultActiveKey="1" layout="fixed">
        <Tabs.TabPane tab="用户信息" key="1">
          <Form layout="vertical">
            <Form.Item label="用户名" {...this.formLayout}>
              {getFieldDecorator('name', {
                validateFirst: true,
                rules: [
                  {
                    required: true,
                    message: '请输入用户名',
                  },
                  {
                    validator: async (rule, value, callback) => {
                      if (!value || value.trim() === '') return callback()
                      // await dispatch(createAction('user/valid')({
                      //   id,
                      //   value
                      // }));
                      // valid ? callback() : callback('用户名已存在');
                      const data = await check({
                            id,
                            value,
                          })
                      data.valid ? callback() : callback('用户名已存在');
                    },
                  },
                ],
                initialValue: data.name,
              })(<Input placeholder="请输入" />)}
            </Form.Item>
            {!id && (
              <React.Fragment>
                <Form.Item label="密码" {...this.formLayout}>
                  {getFieldDecorator('password', {
                    rules: [
                      {
                        required: true,
                        message: '请输入密码',
                      },
                      {
                        validator: this.validateToNextPassword,
                      },
                    ],
                  })(<Input.Password placeholder="请输入" />)}
                </Form.Item>
                <Form.Item label="确认密码" {...this.formLayout}>
                  {getFieldDecorator('confirmPassword', {
                    rules: [
                      {
                        required: true,
                        message: '请输入密码',
                      },
                      {
                        validator: this.compareToFirstPassword,
                      },
                    ],
                  })(<Input.Password placeholder="请输入" onBlur={this.handleConfirmBlur} />)}
                </Form.Item>
              </React.Fragment>
            )}
            <Form.Item label="真实姓名" {...this.formLayout}>
              {getFieldDecorator('realname', {
                rules: [{ required: true, message: '请输入真实姓名' }],
                initialValue: data.realname,
              })(<Input placeholder="请输入" />)}
            </Form.Item>
            <Form.Item label="联系电话" {...this.formLayout}>
              {getFieldDecorator('phone', {
                rules: [
                  {
                    pattern: /^\d{11}$/,
                    message: '请输入十一位手机号码',
                  },
                ],
                initialValue: data.phone,
              })(<Input placeholder="请输入" />)}
            </Form.Item>
            <Form.Item label="email" {...this.formLayout}>
              {getFieldDecorator('email', {
                rules: [
                  {
                    type: 'email',
                    message: '请输入正确的电子邮箱',
                  },
                ],
                initialValue: data.email,
              })(<Input placeholder="请输入" />)}
            </Form.Item>
          </Form>
        </Tabs.TabPane>
        <Tabs.TabPane tab="所属角色" key="2">
          <Transfer
            rowKey={record => record.id}
            showSearch
            dataSource={roles}
            listStyle={{
              width: 210,
              height: 340,
            }}
            // showSearch
            // filterOption={this.filterOption}
            targetKeys={targetKeys}
            onChange={this.handleChange}
            render={item => item.name}
          />
        </Tabs.TabPane>
        <Tabs.TabPane tab="所属部门" key="3">
          <Tree
            checkable
            multiple
            showIcon
            loadData={this.onLoadData}
            checkedKeys={checkedKeys}
            // selectedKeys={selectedKeys}
            // checkStrictly
            rowKey={record => record.id}
            onCheck={this.onCheck}
            onSelect={this.onSelect}
          >
            {this.renderTreeNodes(groups)}
          </Tree>
        </Tabs.TabPane>
      </Tabs>
    );
  }
}

const UserPage = props => {
  const dispatch = useDispatch()
  const [selectedRows, setSelectedRows] = useState([])
  const { list: { data, total }, params = {} } = useSelector(_ => _.user)
  const { effects } = useSelector(_ => _.loading)
  const loading = effects['user/fetchList']

  const columns = [
    {
      title: '用户名',
      dataIndex: 'name',
      width: 200,
    },
    {
      title: '真实姓名',
      dataIndex: 'realname',
      width: 120,
      align: 'center',
    },
    {
      title: '邮箱',
      dataIndex: 'mail',
      width: 200,
    },
    {
      title: '手机号码',
      dataIndex: 'phone',
      width: 150,
    },
    {
      title: '所属部门',
      dataIndex: 'org',
      width: 200,
    },
    {
      title: '当前状态',
      dataIndex: 'enabled',
      width: 100,
      align: 'center',
    },
    {
      title: '创建时间',
      dataIndex: 'crtime',
      width: 200,
      align: 'center',
    },
  ];

  useEffect(() => {
    dispatch(createAction('user/fetchList')());
  }, [dispatch]);

  const handleSelectRows = rows => {
    setSelectedRows(rows)
  };
  const handleAdd = e => {
    dispatch(createAction('user/reset')());
    Dialog.open({
      title: '新建用户',
      fixed: true,
      component: ModelForm,
      url: 'user/add',
      onOk: data => {
        handleReload();
      },
      connect: ({ loading }) => ({
              loading: loading.effects['user/fetchGroups'] && loading.effects['user/fetchRoles'],
            })
    });
  };
  const handleEdit = e => {
    const { id } = selectedRows[0];
    dispatch(createAction('user/reset')());
    Dialog.open({
      title: '修改用户',
      fixed: true,
      url: 'user/update',
      data: {
        id,
      },
      options: {
        type: 'put',
      },
      onOk: data => {
        handleReload();
      },
      component: props => <ModelForm {...props} id={id} />,
      connect: ({ loading }) => ({
        loading:
          loading.effects['user/fetchGroups'] && loading.effects['user/fetchRoles'] && loading.effects['user/fetchOne'],
      }),
    });
  };
  const handleRemove = e => {
    Dialog.confirm({
      title: '确认提示',
      content: '确定要删除已选择的用户？',
      onOk: async () => {
        await dispatch(createAction('user/delete')({
          id: selectedRows.map(_ => _.id)
        }))
        handleReload();
      },
    });
  };
  const handleGridChange = (oldPagination, sorter) => {
    const pagination = getPagination(oldPagination);
    const payload = {
      ...params,
      ...pagination,
    };

    if (sorter.field) {
      payload.sorter = sorter.field;
      payload.order = sorter.order;
    }

    dispatch(createAction('user/fetchList')(payload));
  };
  const handleReload = () => {
    dispatch(createAction('user/fetchList')(params));
  };
  const handleSearch = (value, e) => {
    e.preventDefault();
    const pagination = getPagination({
      pageNumber: 1,
    });
    dispatch(createAction('user/fetchList')({
      ...params,
      ...pagination,
      name: value,
    }));
  };

  const pageNumber = params[settings.pageNumber];
  return (
    <Layout
      toolbar={{
        left: (
          <React.Fragment>
            <Button type="primary" onClick={handleAdd}>
              新建
            </Button>
            <Button onClick={handleEdit} disabled={selectedRows.length !== 1}>
              编辑
            </Button>
            <Button
              type="danger"
              disabled={selectedRows.length === 0}
              onClick={handleRemove}
            >
              删除
            </Button>
          </React.Fragment>
        ),
        right: (
          <Form layout="inline">
            <Input.Search placeholder="请输入要查询的关键词" onSearch={handleSearch} />
            {/*<Button onClick={showSearchPanel}>高级查询</Button>*/}
          </Form>
        ),
      }}
    >
      <Grid
          selectedRows={selectedRows}
          onSelectRow={handleSelectRows}
          columns={columns}
          data={data}
          loading={loading}
          pagination={{
            pageNumber,
            total,
          }}
          onReload={handleReload}
          onChange={handleGridChange}
        />
    </Layout>
  );
}

export default UserPage;
